home *** CD-ROM | disk | FTP | other *** search
/ Just Call Me Internet / Just Call Me Internet.iso / prog / atari / c / nos042_s / tcpin.c < prev    next >
C/C++ Source or Header  |  1994-09-16  |  25KB  |  910 lines

  1. /* Process incoming TCP segments. Page number references are to ARPA RFC-793,
  2.  * the TCP specification.
  3.  *
  4.  * Copyright 1991 Phil Karn, KA9Q
  5.  */
  6.  
  7. /****************************************************************************
  8. *    $Id: tcpin.c 1.2 93/07/16 11:51:15 ROOT_DOS Exp $
  9. *    09 May 93    1.2        GT    Fix warnings.                                    *
  10. *                            Throw away incoming packets when memory is low.    *
  11. *
  12. *  ATARI Version by David Nash - dnash@chaos.demon.co.uk
  13. *
  14. ****************************************************************************/
  15.  
  16. #include "global.h"
  17. #include "timer.h"
  18. #include "mbuf.h"
  19. #include "netuser.h"
  20. #include "internet.h"
  21. #include "tcp.h"
  22. #include "icmp.h"
  23. #include "iface.h"
  24. #include "ip.h"
  25.  
  26. static void update __ARGS((struct tcb *tcb,struct tcp *seg,int16 length));
  27. static void proc_syn __ARGS((struct tcb *tcb,char tos,struct tcp *seg));
  28. static void add_reseq __ARGS((struct tcb *tcb,char tos,struct tcp *seg,
  29.     struct mbuf *bp,int16 length));
  30. static void get_reseq __ARGS((struct tcb *tcb,char *tos,struct tcp *seq,
  31.     struct mbuf **bp,int16 *length));
  32. static int trim __ARGS((struct tcb *tcb,struct tcp *seg,struct mbuf **bpp,
  33.     int16 *length));
  34. static int in_window __ARGS((struct tcb *tcb,int32 seq));
  35.  
  36. /* This function is called from IP with the IP header in machine byte order,
  37.  * along with a mbuf chain pointing to the TCP header.
  38.  */
  39. void
  40. tcp_input(iface,ip,bp,rxbroadcast)
  41. struct iface *iface;    /* Incoming interface (ignored) */
  42. struct mbuf *bp;    /* Data field, if any */
  43. struct ip *ip;        /* IP header */
  44. int rxbroadcast;    /* Incoming broadcast - discard if true */
  45. {
  46.     struct tcb *ntcb;
  47.     register struct tcb *tcb;    /* TCP Protocol control block */
  48.     struct tcp seg;            /* Local copy of segment header */
  49.     struct connection conn;        /* Local copy of addresses */
  50.     struct pseudo_header ph;    /* Pseudo-header for checksumming */
  51.     int hdrlen;            /* Length of TCP header */
  52.     int16 length;
  53.  
  54.     if(bp == NULLBUF)
  55.         return;
  56.  
  57.     tcpInSegs++;
  58.     if(rxbroadcast){
  59.         /* Any TCP packet arriving as a broadcast is
  60.          * to be completely IGNORED!!
  61.          */
  62.         free_p(bp);
  63.         return;
  64.     }
  65.  
  66.     if (availmem () < Memthresh)
  67.         {
  68.         /* Too little memory - throw away packet. */
  69.  
  70.         tcpInErrs++;
  71.         free_p (bp);
  72.         return;
  73.         }
  74.         
  75.     length = ip->length - IPLEN - ip->optlen;
  76.     ph.source = ip->source;
  77.     ph.dest = ip->dest;
  78.     ph.protocol = ip->protocol;
  79.     ph.length = length;
  80.     if(cksum(&ph,bp,length) != 0){
  81.         /* Checksum failed, ignore segment completely */
  82.         tcpInErrs++;
  83.         free_p(bp);
  84.         return;
  85.     }
  86.     /* Form local copy of TCP header in host byte order */
  87.     if((hdrlen = ntohtcp(&seg,&bp)) < 0){
  88.         /* TCP header is too small */
  89.         free_p(bp);
  90.         return;
  91.     }
  92.     length -= hdrlen;
  93.  
  94.     /* Fill in connection structure and find TCB */
  95.     conn.local.address = ip->dest;
  96.     conn.local.port = seg.dest;
  97.     conn.remote.address = ip->source;
  98.     conn.remote.port = seg.source;
  99.     
  100.     if((tcb = lookup_tcb(&conn)) == NULLTCB){
  101.         /* If this segment doesn't carry a SYN, reject it */
  102.         if(!seg.flags.syn){
  103.             free_p(bp);
  104.             reset(ip,&seg);
  105.             return;
  106.         }
  107.         /* See if there's a TCP_LISTEN on this socket with
  108.          * unspecified remote address and port
  109.          */
  110.         conn.remote.address = 0;
  111.         conn.remote.port = 0;
  112.         if((tcb = lookup_tcb(&conn)) == NULLTCB){
  113.             /* Nope, try unspecified local address too */
  114.             conn.local.address = 0;
  115.             if((tcb = lookup_tcb(&conn)) == NULLTCB){
  116.                 /* No LISTENs, so reject */
  117.                 free_p(bp);
  118.                 reset(ip,&seg);
  119.                 return;
  120.             }
  121.         }
  122.         /* We've found an server listen socket, so clone the TCB */
  123.         if(tcb->flags.clone){
  124.             ntcb = (struct tcb *)mallocw(sizeof (struct tcb));
  125.             ASSIGN(*ntcb,*tcb);
  126.             tcb = ntcb;
  127.             tcb->timer.arg = tcb;
  128.             /* Put on list */
  129.             tcb->next = Tcbs;
  130.             Tcbs = tcb;
  131.         }
  132.         /* Put all the socket info into the TCB */
  133.         tcb->conn.local.address = ip->dest;
  134.         tcb->conn.remote.address = ip->source;
  135.         tcb->conn.remote.port = seg.source;
  136.     }
  137.     tcb->flags.congest = ip->flags.congest;
  138.     /* Do unsynchronized-state processing (p. 65-68) */
  139.     switch(tcb->state){
  140.     case TCP_CLOSED:
  141.         free_p(bp);
  142.         reset(ip,&seg);
  143.         return;
  144.     case TCP_LISTEN:
  145.         if(seg.flags.rst){
  146.             free_p(bp);
  147.             return;
  148.         }
  149.         if(seg.flags.ack){
  150.             free_p(bp);
  151.             reset(ip,&seg);
  152.             return;
  153.         }
  154.         if(seg.flags.syn){
  155.             /* (Security check is bypassed) */
  156.             /* page 66 */
  157.             proc_syn(tcb,ip->tos,&seg);
  158.             send_syn(tcb);
  159.             setstate(tcb,TCP_SYN_RECEIVED);        
  160.             if(length != 0 || seg.flags.fin) {
  161.                 /* Continue processing if there's more */
  162.                 break;
  163.             }
  164.             tcp_output(tcb);
  165.         }
  166.         free_p(bp);    /* Unlikely to get here directly */
  167.         return;
  168.     case TCP_SYN_SENT:
  169.         if(seg.flags.ack){
  170.             if(!seq_within(seg.ack,tcb->iss+1,tcb->snd.nxt)){
  171.                 free_p(bp);
  172.                 reset(ip,&seg);
  173.                 return;
  174.             }
  175.         }
  176.         if(seg.flags.rst){    /* p 67 */
  177.             if(seg.flags.ack){
  178.                 /* The ack must be acceptable since we just checked it.
  179.                  * This is how the remote side refuses connect requests.
  180.                  */
  181.                 close_self(tcb,RESET);
  182.             }
  183.             free_p(bp);
  184.             return;
  185.         }
  186.         /* (Security check skipped here) */
  187.         /* Check incoming precedence; it must match if there's an ACK */
  188.         if(seg.flags.ack && PREC(ip->tos) != PREC(tcb->tos)){
  189.             free_p(bp);
  190.             reset(ip,&seg);
  191.             return;
  192.         }
  193.         if(seg.flags.syn){
  194.             proc_syn(tcb,ip->tos,&seg);
  195.             if(seg.flags.ack){
  196.                 /* Our SYN has been acked, otherwise the ACK
  197.                  * wouldn't have been valid.
  198.                  */
  199.                 update(tcb,&seg,length);
  200.                 setstate(tcb,TCP_ESTABLISHED);
  201.             } else {
  202.                 setstate(tcb,TCP_SYN_RECEIVED);
  203.             }
  204.             if(length != 0 || seg.flags.fin) {
  205.                 break;        /* Continue processing if there's more */
  206.             }
  207.             tcp_output(tcb);
  208.         } else {
  209.             free_p(bp);    /* Ignore if neither SYN or RST is set */
  210.         }
  211.         return;
  212.     }
  213.     /* We reach this point directly in any synchronized state. Note that
  214.      * if we fell through from LISTEN or SYN_SENT processing because of a
  215.      * data-bearing SYN, window trimming and sequence testing "cannot fail".
  216.      */
  217.  
  218.     /* Trim segment to fit receive window. */
  219.     if(trim(tcb,&seg,&bp,&length) == -1){
  220.         /* Segment is unacceptable */
  221.         if(!seg.flags.rst){    /* NEVER answer RSTs */
  222.             /* In SYN_RECEIVED state, answer a retransmitted SYN 
  223.              * with a retransmitted SYN/ACK.
  224.              */
  225.             if(tcb->state == TCP_SYN_RECEIVED)
  226.                 tcb->snd.ptr = tcb->snd.una;
  227.             tcb->flags.force = 1;
  228.             tcp_output(tcb);
  229.         }
  230.         return;
  231.     }
  232.     /* If segment isn't the next one expected, and there's data
  233.      * or flags associated with it, put it on the resequencing
  234.      * queue, ACK it and return.
  235.      *
  236.      * Processing the ACK in an out-of-sequence segment without
  237.      * flags or data should be safe, however.
  238.      */
  239.     if(seg.seq != tcb->rcv.nxt
  240.      && (length != 0 || seg.flags.syn || seg.flags.fin)){
  241.         add_reseq(tcb,ip->tos,&seg,bp,length);
  242.         tcb->flags.force = 1;
  243.         tcp_output(tcb);
  244.         return;
  245.     }
  246.     /* This loop first processes the current segment, and then
  247.      * repeats if it can process the resequencing queue.
  248.      */
  249.     for(;;){
  250.         /* We reach this point with an acceptable segment; all data and flags
  251.          * are in the window, and the starting sequence number equals rcv.nxt
  252.          * (p. 70)
  253.          */    
  254.         if(seg.flags.rst){
  255.             if(tcb->state == TCP_SYN_RECEIVED
  256.              && !tcb->flags.clone && !tcb->flags.active){
  257.                 /* Go back to listen state only if this was
  258.                  * not a cloned or active server TCB
  259.                  */
  260.                 setstate(tcb,TCP_LISTEN);
  261.             } else {
  262.                 close_self(tcb,RESET);
  263.             }
  264.             free_p(bp);
  265.             return;
  266.         }
  267.         /* (Security check skipped here) p. 71 */
  268.         /* Check for precedence mismatch or erroneous extra SYN */
  269.         if(PREC(ip->tos) != PREC(tcb->tos) || seg.flags.syn){
  270.             free_p(bp);
  271.             reset(ip,&seg);
  272.             return;
  273.         }
  274.         /* Check ack field p. 72 */
  275.         if(!seg.flags.ack){
  276.             free_p(bp);    /* All segments after synchronization must have ACK */
  277.             return;
  278.         }
  279.         /* Process ACK */
  280.         switch(tcb->state){
  281.         case TCP_SYN_RECEIVED:
  282.             if(seq_within(seg.ack,tcb->snd.una+1,tcb->snd.nxt)){
  283.                 update(tcb,&seg,length);
  284.                 setstate(tcb,TCP_ESTABLISHED);
  285.             } else {
  286.                 free_p(bp);
  287.                 reset(ip,&seg);
  288.                 return;
  289.             }
  290.             break;
  291.         case TCP_ESTABLISHED:
  292.         case TCP_CLOSE_WAIT:
  293.             update(tcb,&seg,length);
  294.             break;
  295.         case TCP_FINWAIT1:    /* p. 73 */
  296.             update(tcb,&seg,length);
  297.             if(tcb->sndcnt == 0){
  298.                 /* Our FIN is acknowledged */
  299.                 setstate(tcb,TCP_FINWAIT2);
  300.             }
  301.             break;
  302.         case TCP_FINWAIT2:
  303.             update(tcb,&seg,length);
  304.             break;
  305.         case TCP_CLOSING:
  306.             update(tcb,&seg,length);
  307.             if(tcb->sndcnt == 0){
  308.                 /* Our FIN is acknowledged */
  309.                 setstate(tcb,TCP_TIME_WAIT);
  310.                 set_timer(&tcb->timer,MSL2*1000L);
  311.                 start_timer(&tcb->timer);
  312.             }
  313.             break;
  314.         case TCP_LAST_ACK:
  315.             update(tcb,&seg,length);
  316.             if(tcb->sndcnt == 0){
  317.                 /* Our FIN is acknowledged, close connection */
  318.                 close_self(tcb,NORMAL);
  319.                 return;
  320.             }            
  321.             break;
  322.         case TCP_TIME_WAIT:
  323.             start_timer(&tcb->timer);
  324.             break;
  325.         }
  326.  
  327.         /* (URGent bit processing skipped here) */
  328.  
  329.         /* Process the segment text, if any, beginning at rcv.nxt (p. 74) */
  330.         if(length != 0){
  331.             switch(tcb->state){
  332.             case TCP_SYN_RECEIVED:
  333.             case TCP_ESTABLISHED:
  334.             case TCP_FINWAIT1:
  335.             case TCP_FINWAIT2:
  336.                 /* Place on receive queue */
  337.                 append(&tcb->rcvq,bp);
  338.                 tcb->rcvcnt += length;
  339.                 tcb->rcv.nxt += length;
  340.                 tcb->rcv.wnd -= length;
  341.                 tcb->flags.force = 1;
  342.                 /* Notify user */
  343.                 if(tcb->r_upcall)
  344.                     (*tcb->r_upcall)(tcb,tcb->rcvcnt);
  345.                 break;
  346.             default:
  347.                 /* Ignore segment text */
  348.                 free_p(bp);
  349.                 break;
  350.             }
  351.         }
  352.         /* process FIN bit (p 75) */
  353.         if(seg.flags.fin){
  354.             tcb->flags.force = 1;    /* Always respond with an ACK */
  355.  
  356.             switch(tcb->state){
  357.             case TCP_SYN_RECEIVED:
  358.             case TCP_ESTABLISHED:
  359.                 tcb->rcv.nxt++;
  360.                 setstate(tcb,TCP_CLOSE_WAIT);
  361.                 break;
  362.             case TCP_FINWAIT1:
  363.                 tcb->rcv.nxt++;
  364.                 if(tcb->sndcnt == 0){
  365.                     /* Our FIN has been acked; bypass TCP_CLOSING state */
  366.                     setstate(tcb,TCP_TIME_WAIT);
  367.                     set_timer(&tcb->timer,MSL2*1000L);
  368.                     start_timer(&tcb->timer);
  369.                 } else {
  370.                     setstate(tcb,TCP_CLOSING);
  371.                 }
  372.                 break;
  373.             case TCP_FINWAIT2:
  374.                 tcb->rcv.nxt++;
  375.                 setstate(tcb,TCP_TIME_WAIT);
  376.                 set_timer(&tcb->timer,MSL2*1000L);
  377.                 start_timer(&tcb->timer);
  378.                 break;
  379.             case TCP_CLOSE_WAIT:
  380.             case TCP_CLOSING:
  381.             case TCP_LAST_ACK:
  382.                 break;        /* Ignore */
  383.             case TCP_TIME_WAIT:    /* p 76 */
  384.                 start_timer(&tcb->timer);
  385.                 break;
  386.             }
  387.             /* Call the client again so he can see EOF */
  388.             if(tcb->r_upcall)
  389.                 (*tcb->r_upcall)(tcb,tcb->rcvcnt);
  390.         }
  391.         /* Scan the resequencing queue, looking for a segment we can handle,
  392.          * and freeing all those that are now obsolete.
  393.          */
  394.         while(tcb->reseq != NULLRESEQ && seq_ge(tcb->rcv.nxt,tcb->reseq->seg.seq)){
  395.             get_reseq(tcb,&ip->tos,&seg,&bp,&length);
  396.             if(trim(tcb,&seg,&bp,&length) == 0)
  397.                 goto gotone;
  398.             /* Segment is an old one; trim has freed it */
  399.         }
  400.         break;
  401. gotone:    ;
  402.     }
  403.     tcp_output(tcb);    /* Send any necessary ack */
  404. }
  405.  
  406. /* Process an incoming ICMP response */
  407.  
  408. void tcp_icmp(
  409.     int32 icsource,            /* Sender of ICMP message (not used) */
  410.     int32 source,                /* Original IP datagram source (i.e. us) */
  411.     int32 dest,                    /* Original IP datagram dest (i.e., them) */
  412.     char type,
  413.     char code,                    /* ICMP error codes */
  414.     struct mbuf **bpp)        /* First 8 bytes of TCP header */
  415. {
  416.     struct tcp seg;
  417.     struct connection conn;
  418.     register struct tcb *tcb;
  419.  
  420.     /* Extract the socket info from the returned TCP header fragment
  421.      * Note that since this is a datagram we sent, the source fields
  422.      * refer to the local side.
  423.      */
  424.     ntohtcp(&seg,bpp);
  425.     conn.local.port = seg.source;
  426.     conn.remote.port = seg.dest;
  427.     conn.local.address = source;
  428.     conn.remote.address = dest;
  429.     if((tcb = lookup_tcb(&conn)) == NULLTCB)
  430.         return;    /* Unknown connection, ignore */
  431.  
  432.     /* Verify that the sequence number in the returned segment corresponds
  433.      * to something currently unacknowledged. If not, it can safely
  434.      * be ignored.
  435.      */
  436.     if(!seq_within(seg.seq,tcb->snd.una,tcb->snd.nxt))
  437.         return;
  438.  
  439.     /* Destination Unreachable and Time Exceeded messages never kill a
  440.      * connection; the info is merely saved for future reference.
  441.      */
  442.     switch(uchar(type)){
  443.     case ICMP_DEST_UNREACH:
  444.     case ICMP_TIME_EXCEED:
  445.         tcb->type = type;
  446.         tcb->code = code;
  447.         break;
  448.     case ICMP_QUENCH:
  449.         /* Source quench; cut the congestion window in half,
  450.          * but don't let it go below one packet
  451.          */
  452.         tcb->cwind /= 2;
  453.         tcb->cwind = max(tcb->mss,tcb->cwind);
  454.         break;
  455.     }
  456. }
  457. /* Send an acceptable reset (RST) response for this segment
  458.  * The RST reply is composed in place on the input segment
  459.  */
  460. void
  461. reset(ip,seg)
  462. struct ip *ip;            /* Offending IP header */
  463. register struct tcp *seg;    /* Offending TCP header */
  464. {
  465.     struct mbuf *hbp;
  466.     struct pseudo_header ph;
  467.     int16 tmp;
  468.  
  469.     if(seg->flags.rst)
  470.         return;    /* Never send an RST in response to an RST */
  471.  
  472.     /* Compose the RST IP pseudo-header, swapping addresses */
  473.     ph.source = ip->dest;
  474.     ph.dest = ip->source;
  475.     ph.protocol = TCP_PTCL;
  476.     ph.length = TCPLEN;
  477.  
  478.     /* Swap port numbers */
  479.     tmp = seg->source;
  480.     seg->source = seg->dest;
  481.     seg->dest = tmp;
  482.  
  483.     if(seg->flags.ack){
  484.         /* This reset is being sent to clear a half-open connection.
  485.          * Set the sequence number of the RST to the incoming ACK
  486.          * so it will be acceptable.
  487.          */
  488.         seg->flags.ack = 0;
  489.         seg->seq = seg->ack;
  490.         seg->ack = 0;
  491.     } else {
  492.         /* We're rejecting a connect request (SYN) from TCP_LISTEN state
  493.          * so we have to "acknowledge" their SYN.
  494.          */
  495.         seg->flags.ack = 1;
  496.         seg->ack = seg->seq;
  497.         seg->seq = 0;
  498.         if(seg->flags.syn)
  499.             seg->ack++;
  500.     }
  501.     /* Set remaining parts of packet */
  502.     seg->flags.urg = 0;
  503.     seg->flags.psh = 0;
  504.     seg->flags.rst = 1;
  505.     seg->flags.syn = 0;
  506.     seg->flags.fin = 0;
  507.     seg->wnd = 0;
  508.     seg->up = 0;
  509.     seg->mss = 0;
  510.     seg->optlen = 0;
  511.     if((hbp = htontcp(seg,NULLBUF,&ph)) == NULLBUF)
  512.         return;
  513.     /* Ship it out (note swap of addresses) */
  514.     ip_send(ip->dest,ip->source,TCP_PTCL,ip->tos,0,hbp,ph.length,0,0);
  515.     tcpOutRsts++;
  516. }
  517.  
  518. /* Process an incoming acknowledgement and window indication.
  519.  * From page 72.
  520.  */
  521.  
  522. static void update(
  523.     struct tcb *tcb,
  524.     struct tcp *seg,
  525.     int16 length )
  526. {
  527.     int16 acked;
  528.     int16 expand;
  529.  
  530.     acked = 0;
  531.     if(seq_gt(seg->ack,tcb->snd.nxt)){
  532.         tcb->flags.force = 1;    /* Acks something not yet sent */
  533.         return;
  534.     }
  535.     /* Decide if we need to do a window update.
  536.      * This is always checked whenever a legal ACK is received,
  537.      * even if it doesn't actually acknowledge anything,
  538.      * because it might be a spontaneous window reopening.
  539.      */
  540.     if(seq_gt(seg->seq,tcb->snd.wl1) || ((seg->seq == tcb->snd.wl1) 
  541.      && seq_ge(seg->ack,tcb->snd.wl2))){
  542.         /* If the window had been closed, crank back the
  543.          * send pointer so we'll immediately resume transmission.
  544.          * Otherwise we'd have to wait until the next probe.
  545.          */
  546.         if(tcb->snd.wnd == 0 && seg->wnd != 0)
  547.             tcb->snd.ptr = tcb->snd.una;
  548.         tcb->snd.wnd = seg->wnd;
  549.         tcb->snd.wl1 = seg->seq;
  550.         tcb->snd.wl2 = seg->ack;
  551.     }
  552.     /* See if anything new is being acknowledged */
  553.     if(!seq_gt(seg->ack,tcb->snd.una)){
  554.         if(seg->ack != tcb->snd.una)
  555.             return;    /* Old ack, ignore */
  556.  
  557.         if(length != 0 || seg->flags.syn || seg->flags.fin)
  558.             return;    /* Nothing acked, but there is data */
  559.  
  560.         /* Van Jacobson "fast recovery" code */
  561.         if(++tcb->dupacks == TCPDUPACKS){
  562.             /* We've had a burst of do-nothing acks, so
  563.              * we almost certainly lost a packet.
  564.              * Resend it now to avoid a timeout. (This is
  565.              * Van Jacobson's 'quick recovery' algorithm.)
  566.              */
  567.             int32 ptrsave;
  568.  
  569.             /* Knock the threshold down just as though
  570.              * this were a timeout, since we've had
  571.              * network congestion.
  572.              */
  573.             tcb->ssthresh = tcb->cwind/2;
  574.             tcb->ssthresh = max(tcb->ssthresh,tcb->mss);
  575.  
  576.             /* Manipulate the machinery in tcp_output() to
  577.              * retransmit just the missing packet
  578.              */
  579.             ptrsave = tcb->snd.ptr;
  580.             tcb->snd.ptr = tcb->snd.una;
  581.             tcb->cwind = tcb->mss;
  582.             tcp_output(tcb);
  583.             tcb->snd.ptr = ptrsave;
  584.  
  585.             /* "Inflate" the congestion window, pretending as
  586.              * though the duplicate acks were normally acking
  587.              * the packets beyond the one that was lost.
  588.              */
  589.             tcb->cwind = tcb->ssthresh + TCPDUPACKS*tcb->mss;
  590.         } else if(tcb->dupacks > TCPDUPACKS){
  591.             /* Continue to inflate the congestion window
  592.              * until the acks finally get "unstuck".
  593.              */
  594.             tcb->cwind += tcb->mss;
  595.         }
  596.         return;
  597.     }
  598.     if(tcb->dupacks >= TCPDUPACKS && tcb->cwind > tcb->ssthresh){
  599.         /* The acks have finally gotten "unstuck". So now we
  600.          * can "deflate" the congestion window, i.e. take it
  601.          * back down to where it would be after slow start
  602.          * finishes.
  603.          */
  604.         tcb->cwind = tcb->ssthresh;
  605.     }
  606.     tcb->dupacks = 0;
  607.  
  608.     /* We're here, so the ACK must have actually acked something */
  609.     acked = seg->ack - tcb->snd.una;
  610.  
  611.     /* Expand congestion window if not already at limit and if
  612.      * this packet wasn't retransmitted
  613.      */
  614.     if(tcb->cwind < tcb->snd.wnd && !tcb->flags.retran){
  615.         if(tcb->cwind < tcb->ssthresh){
  616.             /* Still doing slow start/CUTE, expand by amount acked */
  617.             expand = min(acked,tcb->mss);
  618.         } else {
  619.             /* Steady-state test of extra path capacity */
  620.             expand = ((long)tcb->mss * tcb->mss) / tcb->cwind;
  621.         }
  622.         /* Guard against arithmetic overflow */
  623.         if(tcb->cwind + expand < tcb->cwind)
  624.             expand = (int16) (MAXINT16 - tcb->cwind);
  625.  
  626.         /* Don't expand beyond the offered window */
  627.         if(tcb->cwind + expand > tcb->snd.wnd)
  628.             expand = tcb->snd.wnd - tcb->cwind;
  629.  
  630.         if(expand != 0){
  631. #ifdef    notdef
  632.             /* Kick up the mean deviation estimate to prevent
  633.              * unnecessary retransmission should we already be
  634.              * bandwidth limited
  635.              */
  636.             tcb->mdev += ((long)tcb->srtt * expand) / tcb->cwind;
  637. #endif
  638.             tcb->cwind += expand;
  639.         }
  640.     }
  641.     /* Round trip time estimation */
  642.     if(tcb->flags.rtt_run && seq_ge(seg->ack,tcb->rttseq)){
  643.         /* A timed sequence number has been acked */
  644.         tcb->flags.rtt_run = 0;
  645.         if(!(tcb->flags.retran)){
  646.             int32 rtt;    /* measured round trip time */
  647.             int32 abserr;    /* abs(rtt - srtt) */
  648.  
  649.             /* This packet was sent only once and now
  650.              * it's been acked, so process the round trip time
  651.              */
  652.             rtt = msclock() - tcb->rtt_time;
  653.  
  654.             abserr = (rtt > tcb->srtt) ? rtt - tcb->srtt : tcb->srtt - rtt;
  655.             /* Run SRTT and MDEV integrators, with rounding */
  656.             tcb->srtt = ((AGAIN-1)*tcb->srtt + rtt + (AGAIN/2)) >> LAGAIN;
  657.             tcb->mdev = ((DGAIN-1)*tcb->mdev + abserr + (DGAIN/2)) >> LDGAIN;
  658.  
  659.             rtt_add(tcb->conn.remote.address,rtt);
  660.             /* Reset the backoff level */
  661.             tcb->backoff = 0;
  662.         }
  663.     }
  664.     tcb->sndcnt -= acked;    /* Update virtual byte count on snd queue */
  665.     tcb->snd.una = seg->ack;
  666.  
  667.     /* If we're waiting for an ack of our SYN, note it and adjust count */
  668.     if(!(tcb->flags.synack)){
  669.         tcb->flags.synack = 1;
  670.         acked--;    /* One less byte to pull from real snd queue */
  671.     }
  672.     /* Remove acknowledged bytes from the send queue and update the
  673.      * unacknowledged pointer. If a FIN is being acked,
  674.      * pullup won't be able to remove it from the queue, but that
  675.      * causes no harm.
  676.      */
  677.     pullup(&tcb->sndq,NULLCHAR,acked);
  678.  
  679.     /* Stop retransmission timer, but restart it if there is still
  680.      * unacknowledged data. If there is no more unacked data,
  681.      * the transmitter has gone at least momentarily idle, so
  682.      * record the time for the VJ restart-slowstart rule.
  683.      */    
  684.     stop_timer(&tcb->timer);
  685.     if(tcb->snd.una != tcb->snd.nxt)
  686.         start_timer(&tcb->timer);
  687.     else
  688.         tcb->lastactive = msclock();
  689.  
  690.     /* If retransmissions have been occurring, make sure the
  691.      * send pointer doesn't repeat ancient history
  692.      */
  693.     if(seq_lt(tcb->snd.ptr,tcb->snd.una))
  694.         tcb->snd.ptr = tcb->snd.una;
  695.  
  696.     /* Clear the retransmission flag since the oldest
  697.      * unacknowledged segment (the only one that is ever retransmitted)
  698.      * has now been acked.
  699.      */
  700.     tcb->flags.retran = 0;
  701.  
  702.     /* If outgoing data was acked, notify the user so he can send more
  703.      * unless we've already sent a FIN.
  704.      */
  705.     if(acked != 0 && tcb->t_upcall
  706.      && (tcb->state == TCP_ESTABLISHED || tcb->state == TCP_CLOSE_WAIT)){
  707.         (*tcb->t_upcall)(tcb,tcb->window - tcb->sndcnt);
  708.     }
  709. }
  710.  
  711. /* Determine if the given sequence number is in our receiver window.
  712.  * NB: must not be used when window is closed!
  713.  */
  714. static
  715. int
  716. in_window(tcb,seq)
  717. struct tcb *tcb;
  718. int32 seq;
  719. {
  720.     return seq_within(seq,tcb->rcv.nxt,(int32)(tcb->rcv.nxt+tcb->rcv.wnd-1));
  721. }
  722.  
  723. /* Process an incoming SYN */
  724.  
  725. static void proc_syn(
  726.     struct tcb *tcb,
  727.     char tos,
  728.     struct tcp *seg )
  729. {
  730.     int16 mtu;
  731.     struct tcp_rtt *tp;
  732.  
  733.     tcb->flags.force = 1;    /* Always send a response */
  734.  
  735.     /* Note: It's not specified in RFC 793, but SND.WL1 and
  736.      * SND.WND are initialized here since it's possible for the
  737.      * window update routine in update() to fail depending on the
  738.      * IRS if they are left unitialized.
  739.      */
  740.     /* Check incoming precedence and increase if higher */
  741.     if(PREC(tos) > PREC(tcb->tos))
  742.         tcb->tos = tos;
  743.     tcb->rcv.nxt = seg->seq + 1;    /* p 68 */
  744.     tcb->snd.wl1 = tcb->irs = seg->seq;
  745.     tcb->snd.wnd = seg->wnd;
  746.     if(seg->mss != 0)
  747.         tcb->mss = seg->mss;
  748.     /* Check the MTU of the interface we'll use to reach this guy
  749.      * and lower the MSS so that unnecessary fragmentation won't occur
  750.      */
  751.     if((mtu = ip_mtu(tcb->conn.remote.address)) != 0){
  752.         /* Allow space for the TCP and IP headers */
  753.         mtu -= TCPLEN + IPLEN;
  754.         tcb->cwind = tcb->mss = min(mtu,tcb->mss);
  755.     }
  756.     /* See if there's round-trip time experience */
  757.     if((tp = rtt_get(tcb->conn.remote.address)) != NULLRTT){
  758.         tcb->srtt = tp->srtt;
  759.         tcb->mdev = tp->mdev;
  760.     }
  761. }
  762.  
  763. /* Generate an initial sequence number and put a SYN on the send queue */
  764. void
  765. send_syn(tcb)
  766. register struct tcb *tcb;
  767. {
  768.     tcb->iss = geniss();
  769.     tcb->rttseq = tcb->snd.wl2 = tcb->snd.una = tcb->iss;
  770.     tcb->snd.ptr = tcb->snd.nxt = tcb->rttseq;
  771.     tcb->sndcnt++;
  772.     tcb->flags.force = 1;
  773. }
  774.  
  775. /* Add an entry to the resequencing queue in the proper place */
  776.  
  777. static void add_reseq(
  778.     struct tcb *tcb,
  779.     char tos,
  780.     struct tcp *seg,
  781.     struct mbuf *bp,
  782.     int16 length )
  783. {
  784.     struct reseq *rp,*rp1;
  785.  
  786.     /* Allocate reassembly descriptor */
  787.     if((rp = (struct reseq *)malloc(sizeof (struct reseq))) == NULLRESEQ){
  788.         /* No space, toss on floor */
  789.         free_p(bp);
  790.         return;
  791.     }
  792.     ASSIGN(rp->seg,*seg);
  793.     rp->tos = tos;
  794.     rp->bp = bp;
  795.     rp->length = length;
  796.  
  797.     /* Place on reassembly list sorting by starting seq number */
  798.     rp1 = tcb->reseq;
  799.     if(rp1 == NULLRESEQ || seq_lt(seg->seq,rp1->seg.seq)){
  800.         /* Either the list is empty, or we're less than all other
  801.          * entries; insert at beginning.
  802.          */
  803.         rp->next = rp1;
  804.         tcb->reseq = rp;
  805.     } else {
  806.         /* Find the last entry less than us */
  807.         for(;;){
  808.             if(rp1->next == NULLRESEQ || seq_lt(seg->seq,rp1->next->seg.seq)){
  809.                 /* We belong just after this one */
  810.                 rp->next = rp1->next;
  811.                 rp1->next = rp;
  812.                 break;
  813.             }
  814.             rp1 = rp1->next;
  815.         }
  816.     }
  817. }
  818.  
  819. /* Fetch the first entry off the resequencing queue */
  820. static void
  821. get_reseq(tcb,tos,seg,bp,length)
  822. register struct tcb *tcb;
  823. char *tos;
  824. struct tcp *seg;
  825. struct mbuf **bp;
  826. int16 *length;
  827. {
  828.     register struct reseq *rp;
  829.  
  830.     if((rp = tcb->reseq) == NULLRESEQ)
  831.         return;
  832.  
  833.     tcb->reseq = rp->next;
  834.  
  835.     *tos = rp->tos;
  836.     ASSIGN(*seg,rp->seg);
  837.     *bp = rp->bp;
  838.     *length = rp->length;
  839.     free((char *)rp);
  840. }
  841.  
  842. /* Trim segment to fit window. Return 0 if OK, -1 if segment is
  843.  * unacceptable.
  844.  */
  845. static int
  846. trim(tcb,seg,bpp,length)
  847. register struct tcb *tcb;
  848. register struct tcp *seg;
  849. struct mbuf **bpp;
  850. int16 *length;
  851. {
  852.     long dupcnt,excess;
  853.     int16 len;        /* Segment length including flags */
  854.     char accept = 0;
  855.  
  856.     len = *length;
  857.     if(seg->flags.syn)
  858.         len++;
  859.     if(seg->flags.fin)
  860.         len++;
  861.  
  862.     /* Acceptability tests */
  863.     if(tcb->rcv.wnd == 0){
  864.         /* Only in-order, zero-length segments are acceptable when
  865.          * our window is closed.
  866.          */
  867.         if(seg->seq == tcb->rcv.nxt && len == 0){
  868.             return 0;    /* Acceptable, no trimming needed */
  869.         }
  870.     } else {
  871.         /* Some part of the segment must be in the window */
  872.         if(in_window(tcb,seg->seq)){
  873.             accept++;    /* Beginning is */
  874.         } else if(len != 0){
  875.             if(in_window(tcb,(int32)(seg->seq+len-1)) || /* End is */
  876.              seq_within(tcb->rcv.nxt,seg->seq,(int32)(seg->seq+len-1))){ /* Straddles */
  877.                 accept++;
  878.             }
  879.         }
  880.     }
  881.     if(!accept){
  882.         tcb->rerecv += len;    /* Assume all of it was a duplicate */
  883.         free_p(*bpp);
  884.         return -1;
  885.     }
  886.     if((dupcnt = tcb->rcv.nxt - seg->seq) > 0){
  887.         tcb->rerecv += dupcnt;
  888.         /* Trim off SYN if present */
  889.         if(seg->flags.syn){
  890.             /* SYN is before first data byte */
  891.             seg->flags.syn = 0;
  892.             seg->seq++;
  893.             dupcnt--;
  894.         }
  895.         if(dupcnt > 0){
  896.             pullup(bpp,NULLCHAR,(int16)dupcnt);
  897.             seg->seq += dupcnt;
  898.             *length -= dupcnt;
  899.         }
  900.     }
  901.     if((excess = seg->seq + *length - (tcb->rcv.nxt + tcb->rcv.wnd)) > 0){
  902.         tcb->rerecv += excess;
  903.         /* Trim right edge */
  904.         *length -= excess;
  905.         trim_mbuf(bpp,*length);
  906.         seg->flags.fin = 0;    /* FIN follows last data byte */
  907.     }
  908.     return 0;
  909. }
  910.